﻿using System;
using Loki.Engine;
using Loki.Utils;

namespace Loki.UI.Wpf
{
    public class UnityWpfEngine : LokiObject, ITemplatingEngine
    {
        private static IObjectContext _TemplatesContext;

        private const string CONTEXTE_TEMPLATES_NAME = "UITemplates";

        public UnityWpfEngine()
            : base()
        {
            _TemplatesContext = ToolKit.Engine.CreateContext(CONTEXTE_TEMPLATES_NAME);
        }

        /// <summary>
        /// Loads the templates definitions.
        /// </summary>
        /// <param name="P_TemplatesDefinitions">The templates definitions.</param>
        public void LoadTemplates(params string[] P_TemplatesDefinitions)
        {
            _TemplatesContext.LoadContext(P_TemplatesDefinitions);
        }

        public void LoadTemplates(params IContextInstaller[] P_Installers)
        {
            foreach (var L_Templates in P_Installers)
            {
                L_Templates.Install(_TemplatesContext);
            }
        }

        /// <summary>
        /// Gets the view template for the specified viewmodel.
        /// </summary>
        /// <typeparam name="TViewModel">The type of the viewmodel.</typeparam>
        /// <param name="P_ViewModel">The view model.</param>
        public IView GetView<TViewModel>(TViewModel P_ViewModel) where TViewModel : IViewModel
        {
            IView L_View = GetTemplatedView<IView>(P_ViewModel);
            L_View.ViewModel = P_ViewModel;
            L_View.Clean += L_View_Clean;
            return L_View;
        }

        private void L_View_Clean(object sender, EventArgs e)
        {
            IView L_View = sender as IView;
            if (L_View != null)
            {
                L_View.Clean -= L_View_Clean;
                _TemplatesContext.Release(L_View);
            }
        }

        public IModalView GetModalView<TViewModel>(TViewModel P_ViewModel) where TViewModel : IModalViewModel
        {
            IModalView L_View = GetTemplatedView<IModalView>(P_ViewModel);
            L_View.ViewModel = P_ViewModel;
            L_View.Clean += L_View_Clean2;
            return L_View;
        }

        private void L_View_Clean2(object sender, EventArgs e)
        {
            IModalView L_View = sender as IModalView;
            if (L_View != null)
            {
                L_View.Clean -= L_View_Clean2;
                _TemplatesContext.Release(L_View);
            }
        }

        private IViewType GetTemplatedView<IViewType>(object P_Model, string P_ModelID = null) where IViewType : class
        {
            IViewType L_View = default(IViewType);
            Type L_TemplatedType = P_Model.GetType();
            if (P_ModelID == null)
            {
                L_View = _TemplatesContext.Resolve<IViewType>(L_TemplatedType.FullName);
            }
            else
            {
                L_View = _TemplatesContext.Resolve<IViewType>(P_ModelID);
            }

            return L_View;
        }

        public object GetTemplate(object model)
        {
            throw new NotImplementedException();
        }

        public void RegisterAssociation(Type modelType, Type viewType)
        {
            throw new NotImplementedException();
        }

        public void RegisterAssociation<TModel, TView>()
        {
            throw new NotImplementedException();
        }

        public void LoadByConvention(object conventionManager, params System.Reflection.Assembly[] assemblies)
        {
            throw new NotImplementedException();
        }
    }
}